/**
 * 密码验证工具
 * 提供密码强度检查、验证规则等功能
 */

/**
 * 密码配置
 */
const PASSWORD_CONFIG = {
  MIN_LENGTH: 5,
  MAX_LENGTH: 20,
  REQUIRE_UPPERCASE: false,
  REQUIRE_LOWERCASE: false,
  REQUIRE_NUMBER: false,
  REQUIRE_SPECIAL_CHAR: false,
  SPECIAL_CHARS: '!@#$%^&*(),.?":{}|<>[]\\/-_=+`~'
};

/**
 * 密码强度级别
 */
const STRENGTH_LEVELS = {
  WEAK: 0,
  MEDIUM: 1,
  STRONG: 2,
  VERY_STRONG: 3
};

/**
 * 检查密码长度
 * @param {string} password - 密码
 * @returns {object} 验证结果
 */
function checkLength(password) {
  const length = password.length;
  return {
    valid: length >= PASSWORD_CONFIG.MIN_LENGTH && length <= PASSWORD_CONFIG.MAX_LENGTH,
    message: `密码长度应在${PASSWORD_CONFIG.MIN_LENGTH}-${PASSWORD_CONFIG.MAX_LENGTH}位之间`,
    score: length >= PASSWORD_CONFIG.MIN_LENGTH ? 1 : 0
  };
}

/**
 * 检查是否包含大写字母
 * @param {string} password - 密码
 * @returns {object} 验证结果
 */
function checkUppercase(password) {
  const hasUppercase = /[A-Z]/.test(password);
  return {
    valid: !PASSWORD_CONFIG.REQUIRE_UPPERCASE || hasUppercase,
    message: '密码应包含至少一个大写字母',
    score: hasUppercase ? 1 : 0
  };
}

/**
 * 检查是否包含小写字母
 * @param {string} password - 密码
 * @returns {object} 验证结果
 */
function checkLowercase(password) {
  const hasLowercase = /[a-z]/.test(password);
  return {
    valid: !PASSWORD_CONFIG.REQUIRE_LOWERCASE || hasLowercase,
    message: '密码应包含至少一个小写字母',
    score: hasLowercase ? 1 : 0
  };
}

/**
 * 检查是否包含数字
 * @param {string} password - 密码
 * @returns {object} 验证结果
 */
function checkNumber(password) {
  const hasNumber = /\d/.test(password);
  return {
    valid: !PASSWORD_CONFIG.REQUIRE_NUMBER || hasNumber,
    message: '密码应包含至少一个数字',
    score: hasNumber ? 1 : 0
  };
}

/**
 * 检查是否包含特殊字符
 * @param {string} password - 密码
 * @returns {object} 验证结果
 */
function checkSpecialChar(password) {
  const specialCharRegex = new RegExp(`[${PASSWORD_CONFIG.SPECIAL_CHARS.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')}]`);
  const hasSpecialChar = specialCharRegex.test(password);
  return {
    valid: !PASSWORD_CONFIG.REQUIRE_SPECIAL_CHAR || hasSpecialChar,
    message: '密码应包含至少一个特殊字符',
    score: hasSpecialChar ? 1 : 0
  };
}

/**
 * 检查密码是否包含常见弱密码模式
 * @param {string} password - 密码
 * @returns {object} 验证结果
 */
function checkWeakPatterns(password) {
  const weakPatterns = [
    /123456/,
    /password/i,
    /admin/i,
    /qwerty/i,
    /abc123/i,
    /111111/,
    /000000/,
    /987654/,
    /(.)\1{2,}/ // 连续相同字符
  ];
  
  const hasWeakPattern = weakPatterns.some(pattern => pattern.test(password));
  
  return {
    valid: !hasWeakPattern,
    message: '密码包含常见弱密码模式',
    score: hasWeakPattern ? -1 : 0
  };
}

/**
 * 检查密码是否包含连续字符
 * @param {string} password - 密码
 * @returns {object} 验证结果
 */
function checkSequentialChars(password) {
  const sequences = [
    '0123456789',
    'abcdefghijklmnopqrstuvwxyz',
    'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
    'qwertyuiop',
    'asdfghjkl',
    'zxcvbnm'
  ];
  
  let hasSequence = false;
  
  for (let sequence of sequences) {
    for (let i = 0; i <= sequence.length - 3; i++) {
      const subSeq = sequence.substring(i, i + 3);
      if (password.includes(subSeq) || password.includes(subSeq.split('').reverse().join(''))) {
        hasSequence = true;
        break;
      }
    }
    if (hasSequence) break;
  }
  
  return {
    valid: !hasSequence,
    message: '密码包含连续字符序列',
    score: hasSequence ? -1 : 0
  };
}

/**
 * 综合密码验证
 * @param {string} password - 密码
 * @returns {object} 验证结果
 */
function validatePassword(password) {
  if (!password) {
    return {
      valid: false,
      message: '请输入密码',
      strength: STRENGTH_LEVELS.WEAK,
      score: 0,
      checks: {}
    };
  }
  
  const checks = {
    length: checkLength(password),
    uppercase: checkUppercase(password),
    lowercase: checkLowercase(password),
    number: checkNumber(password),
    specialChar: checkSpecialChar(password),
    weakPatterns: checkWeakPatterns(password),
    sequentialChars: checkSequentialChars(password)
  };
  
  // 计算总分
  let totalScore = 0;
  Object.values(checks).forEach(check => {
    totalScore += check.score;
  });
  
  // 检查是否所有必需规则都通过
  const isValid = Object.values(checks).every(check => check.valid);
  
  // 计算强度级别
  let strength = STRENGTH_LEVELS.WEAK;
  if (totalScore >= 5) {
    strength = STRENGTH_LEVELS.VERY_STRONG;
  } else if (totalScore >= 4) {
    strength = STRENGTH_LEVELS.STRONG;
  } else if (totalScore >= 3) {
    strength = STRENGTH_LEVELS.MEDIUM;
  }
  
  // 获取第一个失败的检查作为错误消息
  const failedCheck = Object.values(checks).find(check => !check.valid);
  
  return {
    valid: isValid,
    message: failedCheck ? failedCheck.message : '密码符合要求',
    strength,
    score: Math.max(0, totalScore),
    checks
  };
}

/**
 * 获取密码强度文本
 * @param {number} strength - 强度级别
 * @returns {string} 强度文本
 */
function getStrengthText(strength) {
  const texts = {
    [STRENGTH_LEVELS.WEAK]: '弱',
    [STRENGTH_LEVELS.MEDIUM]: '中',
    [STRENGTH_LEVELS.STRONG]: '强',
    [STRENGTH_LEVELS.VERY_STRONG]: '很强'
  };
  return texts[strength] || '弱';
}

/**
 * 获取密码强度颜色
 * @param {number} strength - 强度级别
 * @returns {string} 颜色值
 */
function getStrengthColor(strength) {
  const colors = {
    [STRENGTH_LEVELS.WEAK]: '#fa3534',
    [STRENGTH_LEVELS.MEDIUM]: '#ff9500',
    [STRENGTH_LEVELS.STRONG]: '#19be6b',
    [STRENGTH_LEVELS.VERY_STRONG]: '#007aff'
  };
  return colors[strength] || '#fa3534';
}

/**
 * 获取密码强度百分比
 * @param {number} strength - 强度级别
 * @returns {number} 百分比
 */
function getStrengthPercentage(strength) {
  const percentages = {
    [STRENGTH_LEVELS.WEAK]: 25,
    [STRENGTH_LEVELS.MEDIUM]: 50,
    [STRENGTH_LEVELS.STRONG]: 75,
    [STRENGTH_LEVELS.VERY_STRONG]: 100
  };
  return percentages[strength] || 25;
}

/**
 * 检查两个密码是否匹配
 * @param {string} password - 密码
 * @param {string} confirmPassword - 确认密码
 * @returns {object} 验证结果
 */
function validatePasswordMatch(password, confirmPassword) {
  if (!confirmPassword) {
    return {
      valid: false,
      message: '请再次输入密码'
    };
  }
  
  if (password !== confirmPassword) {
    return {
      valid: false,
      message: '两次输入的密码不一致'
    };
  }
  
  return {
    valid: true,
    message: '密码匹配'
  };
}

/**
 * 生成密码建议
 * @param {object} checks - 检查结果
 * @returns {Array} 建议列表
 */
function generatePasswordSuggestions(checks) {
  const suggestions = [];
  
  if (!checks.length.valid) {
    suggestions.push(`密码长度应为${PASSWORD_CONFIG.MIN_LENGTH}-${PASSWORD_CONFIG.MAX_LENGTH}位`);
  }
  
  if (!checks.uppercase.valid) {
    suggestions.push('添加至少一个大写字母');
  }
  
  if (!checks.lowercase.valid) {
    suggestions.push('添加至少一个小写字母');
  }
  
  if (!checks.number.valid) {
    suggestions.push('添加至少一个数字');
  }
  
  if (!checks.specialChar.valid) {
    suggestions.push('添加至少一个特殊字符');
  }
  
  if (!checks.weakPatterns.valid) {
    suggestions.push('避免使用常见弱密码模式');
  }
  
  if (!checks.sequentialChars.valid) {
    suggestions.push('避免使用连续字符序列');
  }
  
  return suggestions;
}

module.exports = {
  PASSWORD_CONFIG,
  STRENGTH_LEVELS,
  validatePassword,
  validatePasswordMatch,
  getStrengthText,
  getStrengthColor,
  getStrengthPercentage,
  generatePasswordSuggestions,
  checkLength,
  checkUppercase,
  checkLowercase,
  checkNumber,
  checkSpecialChar,
  checkWeakPatterns,
  checkSequentialChars
}; 